package com.zenchn.exception;

import com.zenchn.entity.HttpResult;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.beans.ConversionNotSupportedException;
import org.springframework.beans.TypeMismatchException;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingPathVariableException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.multipart.support.MissingServletRequestPartException;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.servlet.http.HttpServletRequest;

/**
 * 全局异常处理
 *
 * @author panbingqi
 * @date 2021-06-01
 */
@RestControllerAdvice
public class SpringGlobalExceptionHandler {

    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(value = {
            MissingServletRequestParameterException.class,
            ServletRequestBindingException.class,
            TypeMismatchException.class,
            HttpMessageNotReadableException.class,
            MethodArgumentNotValidException.class,
            MissingServletRequestPartException.class,
            BindException.class
    })
    public HttpResult error400(HttpServletRequest request, Exception ex) {
        ex.printStackTrace();
        HttpResult result = new HttpResult(request.getRequestURI());
        result.setMessage(ex.getMessage());
        result.setStatus(HttpStatus.BAD_REQUEST.value());
        result.setError(HttpStatus.BAD_REQUEST.getReasonPhrase());

        return result;
    }


    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    @ExceptionHandler(value = {UnauthorizedException.class})
    public HttpResult error401(HttpServletRequest request, Exception ex) {
        HttpResult result = new HttpResult(request.getRequestURI());
        result.setMessage("未授权-当前账号无法使用该功能.");
        result.setStatus(HttpStatus.UNAUTHORIZED.value());
        result.setError(HttpStatus.UNAUTHORIZED.getReasonPhrase());
        return result;
    }

    @ResponseStatus(HttpStatus.NOT_FOUND)
    @ExceptionHandler(value = {NoHandlerFoundException.class})
    public HttpResult error404(HttpServletRequest request, Exception ex) {
        HttpResult result = new HttpResult(request.getRequestURI());
        result.setMessage("404-无法找到你需要的页面或接口.");
        result.setStatus(HttpStatus.NOT_FOUND.value());
        result.setError(HttpStatus.NOT_FOUND.getReasonPhrase());
        return result;
    }


    @ResponseStatus(HttpStatus.NOT_ACCEPTABLE)
    @ExceptionHandler(value = {CheckException.class, CustomException.class})
    public HttpResult error406(HttpServletRequest request, Exception ex) {
        HttpResult result = new HttpResult(request.getRequestURI());
        result.setMessage(ex.getMessage());
        result.setStatus(HttpStatus.NOT_ACCEPTABLE.value());
        result.setError(HttpStatus.NOT_ACCEPTABLE.getReasonPhrase());
        return result;
    }


    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(value = {
            HttpMessageNotWritableException.class,
            ConversionNotSupportedException.class,
            MissingPathVariableException.class,
            RuntimeException.class,
            Exception.class
    })
    public HttpResult error500(HttpServletRequest request, Exception ex) {
        ex.printStackTrace();

        String meaasge = ex.getMessage();
        if (null == meaasge && null != ex.getCause()) {
            meaasge = ex.getCause().getMessage();
        }
        if (null == meaasge) {
            meaasge = "服务器内部错误，请联系相关人员.";
        }

        HttpResult result = new HttpResult(request.getRequestURI());
        result.setMessage(meaasge);
        result.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
        result.setError(HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase());
        return result;
    }


}
